package com.vipboot.platform.system.controller.rbac;

import cn.dev33.satoken.annotation.SaCheckPermission;

import com.vipboot.framework.core.domain.R;
import com.vipboot.framework.core.validation.AddGroup;
import com.vipboot.framework.core.validation.EditGroup;
import com.vipboot.framework.log.annotation.Log;
import com.vipboot.framework.log.enums.BusinessType;
import com.vipboot.framework.mybatisplus.core.page.PageData;
import com.vipboot.framework.mybatisplus.core.page.PageQuery;
import com.vipboot.framework.satoken.helper.LoginHelper;
import com.vipboot.platform.system.crud.service.rbac.SysDeptService;
import com.vipboot.platform.system.crud.service.rbac.SysMenuService;
import com.vipboot.platform.system.crud.service.rbac.SysRoleService;
import com.vipboot.platform.system.domain.bo.SysDeptBo;
import com.vipboot.platform.system.domain.bo.SysRoleBo;
import com.vipboot.platform.system.domain.bo.SysUserBo;
import com.vipboot.platform.system.domain.model.TreeCheckedVo;
import com.vipboot.platform.system.domain.vo.SysRoleVo;
import com.vipboot.platform.system.domain.vo.SysUserVo;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 角色信息表 前端控制器
 * </p>
 *
 * @author daze
 * @since 2024-12-10
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/sysRole")
public class SysRoleController {

    private final SysRoleService sysRoleService;
    private final SysMenuService sysMenuService;
    private final SysDeptService sysDeptService;

    /**
     * 分页查询角色信息表。
     *
     * @param pageQuery 分页对象
     * @return 分页对象
     */
    @SaCheckPermission("sysRole:list")
    @GetMapping("/page")
    public R<PageData<SysRoleVo>> page(@ModelAttribute SysRoleBo bo,
                                       @ModelAttribute PageQuery pageQuery) {
        return R.ok(sysRoleService.page(bo, pageQuery));
    }

    /**
     * 添加角色信息表。
     *
     * @param bo 角色信息表
     */
    @SaCheckPermission("sysRole:save")
    @Log(module = "角色管理", title = "添加角色", businessType = BusinessType.Insert)
    @PostMapping("/save")
    public R<Void> save(@Validated(AddGroup.class)
                        @RequestBody SysRoleBo bo) {
        return sysRoleService.save(bo) ? R.ok() : R.fail();
    }


    /**
     * 根据主键更新角色信息表。
     *
     * @param bo 角色信息表
     */
    @SaCheckPermission("sysRole:update")
    @Log(module = "角色管理", title = "更新角色", businessType = BusinessType.Update)
    @PostMapping("/update")
    public R<Void> update(@Validated(EditGroup.class)
                          @RequestBody SysRoleBo bo) {
        return sysRoleService.update(bo) ? R.ok() : R.fail();
    }


    /**
     * 根据主键删除角色信息表。
     *
     * @param id 主键
     */
    @SaCheckPermission("sysRole:remove")
    @Log(module = "角色管理", title = "删除角色", businessType = BusinessType.Delete)
    @PostMapping("/remove/{id}")
    public R<Void> remove(@NotNull(message = "主键不能为空")
                          @PathVariable Long id) {
        return sysRoleService.removeByIds(List.of(id)) ? R.ok() : R.fail();
    }

    /**
     * 查询当前角色已分配的用户列表 / 可条件搜索
     */
//    @SaCheckPermission("system:role:list")
    @GetMapping("/authUser/allocatedList")
    public R<PageData<SysUserVo>> allocatedList(@ModelAttribute SysUserBo bo,
                                                @ModelAttribute PageQuery pageQuery) {
        return R.ok(sysRoleService.pageAllocatedUser(bo, pageQuery));
    }

    /**
     * 查询当前角色未分配的用户列表 (用户列表包括其他角色已分配的用户) / 可条件搜索
     */
//    @SaCheckPermission("system:role:list")
    @GetMapping("/authUser/unAllocatedList")
    public R<PageData<SysUserVo>> unAllocatedList(@ModelAttribute SysUserBo bo,
                                                  @ModelAttribute PageQuery pageQuery) {
        return R.ok(sysRoleService.pageUnAllocatedUser(bo, pageQuery));
    }

    /**
     * 取消授权用户
     */
//    @SaCheckPermission("system:role:edit")
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @Log(module = "角色管理", title = "取消授权用户", businessType = BusinessType.Grant)
    @PostMapping("/authUser/cancel")
    public R<Void> cancelAuthUser(Long roleId, Long userId) {
        return sysRoleService.cancelAuthUser(roleId, userId) ? R.ok()
                : R.fail("取消授权用户角色失败，请联系管理员");
    }

    /**
     * 批量取消授权用户
     */
//    @SaCheckPermission("system:role:edit")
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @Log(module = "角色管理", title = "批量取消授权用户", businessType = BusinessType.Grant)
    @PostMapping("/authUser/cancelAll")
    public R<Void> cancelAllAuthUser(Long roleId, Long[] userIds) {
        return sysRoleService.cancelAllAuthUser(roleId, userIds) ? R.ok()
                : R.fail("取消授权用户角色失败，请联系管理员");
    }

    /**
     * 角色授权用户
     */
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @Log(module = "角色管理", title = "角色授权用户", businessType = BusinessType.Grant)
    @PostMapping("/authUser")
    public R<Void> authUser(Long roleId, Long[] userIds) {
        return sysRoleService.authUser(roleId, userIds) ? R.ok()
                : R.fail("批量选择用户授权失败，请联系管理员");
    }


    /**
     * 角色分配菜单
     */
    @Log(module = "角色管理", title = "角色分配菜单", businessType = BusinessType.Grant)
    @PostMapping("/authMenu")
    public R<Void> authMenu(@RequestBody SysRoleBo bo) {
        return sysRoleService.authMenu(bo) ? R.ok() : R.fail();
    }

    /**
     * 角色分配数据权限
     */
    @Log(module = "角色管理", title = "角色分配数据权限", businessType = BusinessType.Grant)
    @PostMapping("/authDataScope")
    public R<Void> authDataScope(@RequestBody SysRoleBo bo) {
        return sysRoleService.authDataScope(bo) ? R.ok() : R.fail();
    }


    /**
     * 获取对应角色菜单树列表
     */
    @GetMapping(value = "/menuTreeChecked/{roleId}")
    public R<TreeCheckedVo> menuTreeChecked(@PathVariable("roleId") Long roleId) {
        TreeCheckedVo treeCheckedVo = new TreeCheckedVo();
        treeCheckedVo.setCheckedKeys(sysRoleService.listAllocatedMenuIdByRoleId(roleId));
        treeCheckedVo.setTreeList(sysMenuService.tree(LoginHelper.getUserId()));
        return R.ok(treeCheckedVo);
    }

    /**
     * 获取对应角色部门树列表
     */
    @GetMapping(value = "/deptTreeChecked/{roleId}")
    public R<TreeCheckedVo> deptTreeChecked(@PathVariable("roleId") Long roleId) {
        TreeCheckedVo treeCheckedVo = new TreeCheckedVo();
        treeCheckedVo.setCheckedKeys(sysRoleService.listAllocatedDeptIdByRoleId(roleId));
        treeCheckedVo.setTreeList(sysDeptService.tree(new SysDeptBo()));
        return R.ok(treeCheckedVo);
    }


    /**
     * 获取角色选择框列表
     **/
    @GetMapping("/pageOptionSelect")
    public R<PageData<SysRoleVo>> pageOptionSelect(@ModelAttribute PageQuery pageQuery) {
        return R.ok(sysRoleService.pageOptionSelect(pageQuery));
    }

}
